#ifndef CORE_BASIC_TYPES_HPP_
#define CORE_BASIC_TYPES_HPP_

#include <cstddef>         //for nullptr_t
#include <cstdint>         //for intptr_t
#include <climits>         //for FLT_ and DBL_
#include <float.h>

#include "tbcore/predefined.hpp"  //for compiler version

#ifndef nullptr
#	define nullptr 0
#endif

#ifdef TB_COMPILER_MSVC
#	define TB_LONG_LONG(x) x##I64
#	define TB_ULONG_LONG(x) x##UI64
#else
#	define TB_LONG_LONG(x) x##LL
#	define TB_ULONG_LONG(x) x##ULL
#endif

#define TB_INT8(x)    ((int8)x)
#define TB_INT16(x)   ((int16)x)
#define TB_INT32(x)   ((int32)x)
#define TB_INT64(x)   ((int64)TB_LONG_LONG(x))

#define TB_UINT8(x)   ((uint8)(x ## U))
#define TB_UINT16(x)  ((uint16)(x ## U))
#define TB_UINT32(x)  ((uint32)(x ## U))
#define TB_UINT64(x)  ((uint64)TB_ULONG_LONG(x))

typedef unsigned char        uchar;     //1 byte
typedef signed char          schar;     //1 byte
typedef std::int8_t          int8;      //1 byte
typedef std::uint8_t         uint8;     //1 byte
typedef std::int16_t         int16;     //2 bytes
typedef std::uint16_t        uint16;    //2 bytes
typedef std::int32_t         int32;     //4 bytes
typedef std::uint32_t        uint32;    //4 bytes
typedef std::int64_t         int64;     //8 bytes
typedef std::uint64_t        uint64;    //8 bytes

TB_NAMESPACE_BEGIN

struct NoneType {};

const  uint8 kuint8Max      = (( uint8) 0xFF);
const uint16 kuint16Max     = ((uint16) 0xFFFF);
const uint32 kuint32Max     = ((uint32) 0xFFFFFFFF);
const uint64 kuint64Max     = ((uint64) TB_UINT64(0xFFFFFFFFFFFFFFFF));
const   int8 kint8Min       = ((  int8) 0x80);
const   int8 kint8Max       = ((  int8) 0x7F);
const  int16 kint16Min      = (( int16) 0x8000);
const  int16 kint16Max      = (( int16) 0x7FFF);
const  int32 kint32Min      = (( int32) 0x80000000);
const  int32 kint32Max      = (( int32) 0x7FFFFFFF);
const  int64 kint64Min      = (( int64) TB_INT64(0x8000000000000000));
const  int64 kint64Max      = (( int64) TB_INT64(0x7FFFFFFFFFFFFFFF));
const  float kfloatMin      = (( float) FLT_MIN);
const  float kfloatMax      = (( float) FLT_MAX);
const double kdoubleMin     = ((double) DBL_MIN);
const double kdoubleMax     = ((double) DBL_MAX);
const  float kfloatEpsilon  = (( float) FLT_EPSILON);
const double kdoubleEpsilon = ((double) DBL_EPSILON);

TB_NAMESPACE_END

#endif CORE_BASIC_TYPES_HPP_
